/*******************************************************************************
 * 文件名: StorageUnitFormat.java
 * 描    述: 容量/流量单位转换类
 * 创建人: Dean Huang(hudi-112@163.com)
 * 日　期: 2017-12-22
 * 描　述: 文件描述
 * 版　本: 1.0
 *******************************************************************************/

package com.z1.core.format;

public class StorageUnitFormat {

	//转换为B大小常量
	//1KB=1024B
	public static final long KB = 1024L;
	//1MB=1024KB
	public static final long MB = 1024L * KB;
	//1GB=1024MB
	public static final long GB = 1024L * MB;
	//1TB=1024GB
	public static final long TB = 1024L * GB;
	//1PB=1024TB
	public static final long PB = 1024L * TB;
	//1ZB=1024PB
	public static final long ZB = 1024L * PB;
	
	//单位
	public static final char B = 'B';
	public static final char K = 'K';
	public static final char M = 'M';
	public static final char G = 'G';
	public static final char T = 'T';
	public static final char P = 'P';
	public static final char Z = 'Z';
	private static final char[] units = {'B', 'K', 'M', 'G', 'T', 'P', 'Z'};
	private static final long[] unitScales = {1024, 1024, 1024, 1024, 1024, 1024};
	
	private static final int indexOf(char unit) {
		for (int i = 0; i < units.length; i++) {
			if (units[i] == unit) {
				return i;
			}
		}
		return -1;
	}
	
	public static final String formatToString(char unit, long num) {
		int i = indexOf(unit);
		if (-1 == i) {
			return "0" + unit;
		}
		StringBuffer buffer = new StringBuffer();
		long cur = num;
		for (; i < unitScales.length && cur >= unitScales[i]; i++) {
			long t = cur % unitScales[i];
			if (0 != t) {
				buffer.insert(0, t + "" + units[i]);
			}
			cur /= unitScales[i];
		}
		buffer.insert(0, cur + "" + units[i]);
		return buffer.toString();
	}
	
	public static final float formatToFloat(char unit, long num) {
		int i = indexOf(unit);
		if (-1 == i) {
			return 0f;
		}
		float cur = (float)num;
		for (; i < units.length && cur >= unitScales[i]; i++) {
			cur /= unitScales[i];
		}
		return Float.parseFloat(NumberFormat.format("0.00", cur));
	}
	
	public static final String formatToFloatString(char unit, long num) {
		int i = indexOf(unit);
		if (-1 == i) {
			return "0" + unit;
		}
		float cur = (float)num;
		for (; i < units.length && cur >= unitScales[i]; i++) {
			cur /= unitScales[i];
		}
		return NumberFormat.format("0.00", cur) + "" + units[i];
	}
	
	public static final String formatUnitToString(char srcUnit, char destUnit, long num) {
		int s = indexOf(srcUnit);
		int e = indexOf(destUnit);
		if (-1 == s || e == destUnit) {
			return "0" + destUnit;
		}
		StringBuffer buffer = new StringBuffer();
		long cur = num;
		int i = s;
		if (s > e) {
			for (; i > e; i--) {
				cur *= unitScales[i];
			}
			buffer.insert(0, cur + "" + units[i]);
		}
		else if (s < e) {
			for (; i < e && cur >= unitScales[i]; i++) {
				long t = cur % unitScales[i];
				if (0 != t){
					buffer.insert(0, t + "" + units[i]);
				}
				cur /= unitScales[i];
			}
			buffer.insert(0, cur + "" + units[i]);
		}
		else {
			buffer.insert(0, cur + "" + destUnit);
		}
		return buffer.toString();
	}
	
	public static final float formatUnitToFloat(char srcUnit, char destUnit, long num) {
		int s = indexOf(srcUnit);
		int e = indexOf(destUnit);
		if (-1 == s || e == destUnit) {
			return 0f;
		}
		float cur = (float)num;
		int i = s;
		if (s > e) {
			for (; i > e; i--) {
				cur *= unitScales[i];
			}
		}
		else if (s < e) {
			for (; i < e; i++) {
				cur /= unitScales[i];
			}
		}
		return Float.parseFloat(NumberFormat.format("0.00", cur));
	}
	
	public static final String formatUnitToFloatString(char srcUnit, char destUnit, long num) {
		int s = indexOf(srcUnit);
		int e = indexOf(destUnit);
		if (-1 == s || e == destUnit) {
			return "0" + destUnit;
		}
		float cur = (float)num;
		int i = s;
		if (s > e) {
			for (; i > e; i--) {
				cur *= unitScales[i];
			}
		}
		else if (s < e) {
			for (; i < e; i++) {
				cur /= unitScales[i];
			}
		}
		return NumberFormat.format("0.00", cur) + "" + destUnit;
	}
	
	public static void main(String[] args) {
		System.out.println(formatUnitToString(B, M, 2231583951L) + " : " + formatUnitToFloatString(B, M, 2231583951L));
		System.out.println(formatUnitToString(B, M, 1300) + " : " + formatUnitToFloatString(B, M, 1300));
		System.out.println(formatUnitToString(B, M, 1300000) + " : " + formatUnitToFloatString(B, M, 1300000));
		
		System.out.println(formatToString(B, 30724280));
		System.out.println(formatToString(B, 11749304));
		System.out.println(formatToString(B, 13) + " : " + formatToFloatString(B, 13) + " : " + formatToFloat(B, 13));
		System.out.println(formatToString(B, 1300) + " : " + formatToFloatString(B, 1300) + " : " + formatToFloat(B, 1300));
		System.out.println(formatToString(B, 1300000) + " : " + formatToFloatString(B, 1300000) + " : " + formatToFloat(B, 1300000));
	}
	
}
